package cn.iocoder.yudao.module.trade.convert.aftersale;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;

/**
 * 贸易售后转换
 *
 * @author huangweidong
 * @date 2023/05/09
 */
@Mapper
public interface TradeAfterSaleConvert {

    TradeAfterSaleConvert INSTANCE = Mappers.getMapper(TradeAfterSaleConvert.class);

    /**
     * 转换
     *
     * @param createReqVO    创建请求VO
     * @param tradeOrderItem 交易订单项
     * @return {@code TradeAfterSaleDO}
     */
    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(target = "createTime", ignore = true),
            @Mapping(target = "updateTime", ignore = true),
            @Mapping(target = "creator", ignore = true),
            @Mapping(target = "updater", ignore = true),
    })
    TradeAfterSaleDO convert(AppTradeAfterSaleCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItem);

    /**
     * 转换
     *
     * @param userIp          用户ip
     * @param afterSale       售后
     * @param orderProperties 订单属性
     * @return {@code PayRefundCreateReqDTO}
     */
    @Mappings({
            @Mapping(source = "afterSale.applyReason", target = "reason"),
            @Mapping(source = "afterSale.refundPrice", target = "amount")
    })
    PayRefundCreateReqDTO convert(String userIp, TradeAfterSaleDO afterSale,
                                  TradeOrderProperties orderProperties);

    /**
     * 转换
     *
     * @param bean bean
     * @return {@code MemberUserRespVO}
     */
    MemberUserRespVO convert(MemberUserRespDTO bean);

    /**
     * 转换分页
     *
     * @param page 分页
     * @return {@code PageResult<TradeAfterSaleRespPageItemVO>}
     */
    PageResult<TradeAfterSaleRespPageItemVO> convertPage(PageResult<TradeAfterSaleDO> page);

    /**
     * 转换分页
     *
     * @param pageResult           分页结果
     * @param memberUsers          会员用户
     * @param propertyValueDetails 属性值细节
     * @return {@code PageResult<TradeAfterSaleRespPageItemVO>}
     */
    default PageResult<TradeAfterSaleRespPageItemVO> convertPage(PageResult<TradeAfterSaleDO> pageResult,
                                                                 Map<Long, MemberUserRespDTO> memberUsers, List<ProductPropertyValueDetailRespDTO> propertyValueDetails) {
        PageResult<TradeAfterSaleRespPageItemVO> pageVoResult = convertPage(pageResult);
        // 处理会员 + 商品属性等关联信息
        Map<Long, ProductPropertyValueDetailRespDTO> propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId);
        for (int i = 0; i < pageResult.getList().size(); i++) {
            TradeAfterSaleRespPageItemVO afterSaleVO = pageVoResult.getList().get(i);
            TradeAfterSaleDO afterSaleDO = pageResult.getList().get(i);
            // 会员
            afterSaleVO.setUser(convert(memberUsers.get(afterSaleDO.getUserId())));
            // 商品属性
            if (CollUtil.isNotEmpty(afterSaleDO.getProperties())) {
                afterSaleVO.setProperties(new ArrayList<>(afterSaleDO.getProperties().size()));
                // 遍历每个 properties，设置到 TradeOrderPageItemRespVO.Item 中
                afterSaleDO.getProperties().forEach(property -> {
                    ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId());
                    if (propertyValueDetail == null) {
                        return;
                    }
                    afterSaleVO.getProperties().add(convert(propertyValueDetail));
                });
            }
        }
        return pageVoResult;
    }

    /**
     * 转换
     *
     * @param bean bean
     * @return {@code ProductPropertyValueDetailRespVO}
     */
    ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);

    /**
     * ids将属性值
     *
     * @param list 列表
     * @return {@code Set<Long>}
     */
    default Set<Long> convertPropertyValueIds(List<TradeAfterSaleDO> list) {
        if (CollUtil.isEmpty(list)) {
            return new HashSet<>();
        }
        return list.stream().filter(item -> item.getProperties() != null)
                // 遍历多个 Property 属性
                .flatMap(p -> p.getProperties().stream())
                // 将每个 Property 转换成对应的 propertyId，最后形成集合
                .map(TradeOrderItemDO.Property::getValueId)
                .collect(Collectors.toSet());
    }

}
